package com.zh.chat.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.net.InetAddress;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;

import com.zh.chat.controller.ClientContext;
import com.zh.chat.entity.Friend;
import com.zh.chat.entity.UDPProtocol;
import com.zh.chat.entity.UserInfo;
import com.zh.chat.entity.UserStatus;
import com.zh.chat.gui.lable.ImageLabel;
import com.zh.chat.net.voice.ChatReceive;
import com.zh.chat.net.voice.ChatSend;
import com.zh.chat.util.Commons;
import com.zh.chat.util.FileOperationUtil;
import com.zh.chat.util.FileType;

/**
 * 聊天界面
 * @author 逍遥の剑仙
 * 2013-3-1
 */
public class ChatFrame extends JFrame {
	private static final long serialVersionUID = 5524061646763837312L;

	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
	private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private ClientContext clientContext = null;
	private Friend friend = null;

	public Friend getFriend() {
		return friend;
	}

	public void setClientContext(ClientContext clientContext) {
		this.clientContext = clientContext;
	}

	public ChatFrame(Friend friend) {
		this.friend = friend;
		init();
		this.setSize(600, 450);
	}

	private JSplitPane jsp = null;
	private JPanel leftPanel = null;
	private JPanel rightPanel = null;

	private void init() {
		this.setTitle("正在与  " + friend.getSysId() + "  " + friend.getNickname()
				+"（"+Commons.parseStatus(friend.getStatus())+"） 聊天");
		this.setIconImage(createFrameIcon());
		this.setMaximumSize(new Dimension(700, 500));
		this.setContentPane(createContentPane());
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if(receiveThread!=null||sendThread!=null){
					int choose = JOptionPane.showConfirmDialog(null, "您正在语言聊天中是否关闭？");
					if(choose == JOptionPane.CANCEL_OPTION){
						return;
					}else{
						try {
							receiveThread.setRun(false);
							receiveThread.join(500);
							sendThread.setRun(false);
							sendThread.join(500);
						} catch (InterruptedException e1) {e1.printStackTrace();}
					}
				}
				clientContext.destroyChatFrame(friend.getFriendId());
			}
		});
	}

	private ImageIcon sculptureIcon = null;

	private Image createFrameIcon() {
		String path = FileOperationUtil.getFilePath(FileType.SCULPTURE,
				friend.getSysId(), friend.getImage());
		sculptureIcon = new ImageIcon(path);
		Image picImage = sculptureIcon.getImage();
		Image image = new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();
		g.drawImage(picImage, 0, 0, 30, 30, null);
		return image;
	}

	private JPanel createContentPane() {
		JPanel contentPanel = new JPanel(new BorderLayout());
		jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
		jsp.setDividerSize(5);
		jsp.setDoubleBuffered(true);
		jsp.setDividerLocation(420);

		leftPanel = createLeftPanel();// 生成左面板
		rightPanel = createRightPanel();// 生成有面板

		jsp.setLeftComponent(leftPanel);
		jsp.setRightComponent(rightPanel);
		jsp.setResizeWeight(1.0);

		contentPanel.add(jsp, BorderLayout.CENTER);
		return contentPanel;
	}

	private JPanel createRightPanel() {
		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(null);
		rightPanel.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent event) {
				super.componentResized(event);
				Object obj = event.getSource();
				if (obj instanceof JPanel) {
					JPanel panel = (JPanel) obj;
					ImageLabel label = (ImageLabel) panel.getComponent(0);
					label.setSize(panel.getWidth(), 300);
					JPanel infoPanel = (JPanel) panel.getComponent(1);
					infoPanel.setSize(panel.getWidth() - 10,
							panel.getHeight() - 225);
				}
			}
		});
		ImageLabel sculptureLb = new ImageLabel(sculptureIcon);
		sculptureLb.setBounds(5, 5, 80, 80);
		rightPanel.add(sculptureLb);
		JPanel infoPanel = createFriendPanel();
		infoPanel.setBounds(5, 220, 200, 220);
		rightPanel.add(infoPanel);
		rightPanel.add(getVideoBtn());
		rightPanel.setMinimumSize(new Dimension(150, 450));
		rightPanel.setMaximumSize(new Dimension(400, 450));
		return rightPanel;
	}

	private JPanel createFriendPanel() {
		JPanel panel = new JPanel(null);
		JLabel nameLb = new JLabel("昵称:" + friend.getNickname());
		JLabel sexLb = new JLabel("性别:"
				+ (friend.getSex().equals("F") ? "女" : "男"));
		JLabel birthdayLb = new JLabel("生日:"
				+ sdf.format(new java.util.Date(friend.getBirthday())));
		int day = daysBetween(System.currentTimeMillis(),
				friend.getRegisterDate());
		JLabel registDate = new JLabel("SIM年龄:" + day + "天");
		nameLb.setBounds(10, 20, 200, 30);
		sexLb.setBounds(10, 50, 200, 30);
		birthdayLb.setBounds(10, 80, 200, 30);
		registDate.setBounds(10, 110, 200, 30);
		panel.add(nameLb);
		panel.add(birthdayLb);
		panel.add(sexLb);
		panel.add(registDate);
		panel.setBorder(new TitledBorder("SIM号:" + friend.getSysId()));
		return panel;
	}

	private JTextArea logTextArea = null;
	private JLabel videoBtn;
	private JTextArea msgTextArea = null;
	private JButton sendBtn = null;

	private JPanel createLeftPanel() {
		JPanel leftPanel = new JPanel(new BorderLayout());

		JPanel logPanel = new JPanel(new BorderLayout());
		JScrollPane logJsp = new JScrollPane(
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		logTextArea = new JTextArea("加载聊天记录");
		logTextArea.setEditable(false);
		logTextArea.setLineWrap(true);
		logTextArea.setWrapStyleWord(true);
		logTextArea.setBackground(Color.WHITE);
		logTextArea.setBorder(new EmptyBorder(10, 10, 10, 10));
		logJsp.getViewport().add(logTextArea);
		logPanel.add(logJsp, BorderLayout.CENTER);
		logPanel.setBorder(new TitledBorder("聊天记录"));
		logJsp.setMinimumSize(new Dimension(200, 100));
		leftPanel.add(logPanel, BorderLayout.CENTER);

		JPanel inputPanel = new JPanel(new BorderLayout());
		JScrollPane inputJsp = new JScrollPane(
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		inputJsp.setMinimumSize(new Dimension(200, 100));
		inputJsp.setPreferredSize(new Dimension(300, 100));
		msgTextArea = new JTextArea();
		msgTextArea.setEditable(true);
		msgTextArea.setLineWrap(true);
		msgTextArea.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				super.keyPressed(event);
				if (event.isControlDown()
						&& event.getKeyCode() == KeyEvent.VK_S) {
					handleText(msgTextArea);
				}
				if (event.isControlDown()
						&& event.getKeyCode() == KeyEvent.VK_ENTER) {
					handleText(msgTextArea);
				}
				if (event.isShiftDown()
						&& event.getKeyCode() == KeyEvent.VK_ENTER) {
					handleText(msgTextArea);
				}
			}
		});
		inputJsp.getViewport().add(msgTextArea);
		sendBtn = new JButton("发送");
		sendBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				handleText(msgTextArea);
			}
		});
		inputPanel.add(inputJsp, BorderLayout.CENTER);
		inputPanel.add(sendBtn, BorderLayout.EAST);
		inputPanel.setBorder(new TitledBorder("发送消息———可使用Ctrl+Enter"));
		leftPanel.add(inputPanel, BorderLayout.SOUTH);

		return leftPanel;
	}

	private void handleText(JTextArea inputArea) {
		String msg = inputArea.getText();
		if(msg.length() > 1024){
			JOptionPane.showMessageDialog(null, "发送的消息不能超过1024个字符");
		}else{
			inputArea.setText("");
			clientContext.sendMsgToServer(friend, msg);
		}
	}

	public void initLogTextArea() {
		String logStr = clientContext.readChatLog(friend.getFriendId());
		logTextArea.setText(logStr);
	}

	/**
	 * 从聊天记录中读取与该好友的聊天记录
	 */
	public void initChatLog() {
		String log = clientContext.readChatLog(friend.getFriendId());
		if (log != null) {
			logTextArea.setText(log);
		} else {
			logTextArea.setText("");
		}
	}

	public void appendChatLog(UDPProtocol protocol) {
		UserInfo userInfo = clientContext.getUserInfo();
		String msg = (String) protocol.getData();
		String oldStr = logTextArea.getText();
		String newStr = "";
		if (protocol.getRequestId() == 0) {
			newStr = oldStr + "\t\n" + friend.getNickname() + "(" + friend.getFriendId() + ")"
					+ sdf2.format(new java.util.Date(protocol.getReciveTime()))
					+ "\t\n" + msg +"\t\n";
		} else {
			newStr = oldStr + "\t\n" + userInfo.getNickname() + "("
					+ userInfo.getSysId() + ")"
					+ sdf2.format(new java.util.Date(protocol.getReciveTime()))
					+ "\t\n" + msg +"\t\n";
		}
		logTextArea.setText(newStr);
		logTextArea.setCaretPosition(logTextArea.getText().length());
	}

	/**
	 * 计算时间差
	 * 
	 * @param now
	 * @param returnDate
	 * @return
	 */
	private int daysBetween(long now, long returnDate) {
		Calendar cNow = Calendar.getInstance();
		Calendar cReturnDate = Calendar.getInstance();
		cNow.setTimeInMillis(now);
		cReturnDate.setTimeInMillis(returnDate);
		setTimeToMidnight(cNow);
		setTimeToMidnight(cReturnDate);
		long todayMs = cNow.getTimeInMillis();
		long returnMs = cReturnDate.getTimeInMillis();
		long intervalMs = todayMs - returnMs;
		return millisecondsToDays(intervalMs);
	}

	private int millisecondsToDays(long intervalMs) {
		return (int) (intervalMs / (1000 * 86400));
	}

	private void setTimeToMidnight(Calendar calendar) {
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
	}
	
	private int VOICE_IN_LOCAL_PORT;//本地接收端口
	private int VOICE_IN_REMOTE_PORT;//对方接收端口
	private InetAddress VOICE_REMOTE_IP;//对方IP
	private ChatSend sendThread = null;
	private ChatReceive receiveThread = null;
	
	public int getVOICE_IN_LOCAL_PORT() {
		return VOICE_IN_LOCAL_PORT;
	}

	public void setVOICE_IN_LOCAL_PORT(int vOICE_IN_LOCAL_PORT) {
		VOICE_IN_LOCAL_PORT = vOICE_IN_LOCAL_PORT;
	}

	public int getVOICE_IN_REMOTE_PORT() {
		return VOICE_IN_REMOTE_PORT;
	}

	public void setVOICE_IN_REMOTE_PORT(int vOICE_IN_REMOTE_PORT) {
		VOICE_IN_REMOTE_PORT = vOICE_IN_REMOTE_PORT;
	}

	public InetAddress getVOICE_REMOTE_IP() {
		return VOICE_REMOTE_IP;
	}

	public void setVOICE_REMOTE_IP(InetAddress vOICE_REMOTE_IP) {
		VOICE_REMOTE_IP = vOICE_REMOTE_IP;
	}

	public ChatSend getSendThread() {
		return sendThread;
	}

	public void setSendThread(ChatSend sendThread) {
		this.sendThread = sendThread;
	}

	public ChatReceive getReceiveThread() {
		return receiveThread;
	}

	public void setReceiveThread(ChatReceive receiveThread) {
		this.receiveThread = receiveThread;
	}

	private JLabel getVideoBtn() {
		if(videoBtn == null) {
			URL url = ChatFrame.this.getClass().getClassLoader().getResource("com/zh/chat/image/mic.png");
			Image image = new ImageIcon(url).getImage();
			BufferedImage img = new BufferedImage(20, 30, BufferedImage.TRANSLUCENT);
			Graphics g = img.getGraphics();
			g.drawImage(image, 0, 0, 20, 30, null);
			videoBtn = new JLabel(new ImageIcon(img));
			videoBtn.setBounds(10, 190, 40, 30);
			videoBtn.setText("<html>语<br/>音</html>");
			videoBtn.setVerticalTextPosition(JLabel.NORTH);
			videoBtn.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					setVOICE_IN_LOCAL_PORT(clientContext.getNetService().getVOICE_IN_PORT());
					clientContext.readyVoice(friend.getSysId(), friend.getFriendId());
				}
			});
		}
		return videoBtn;
	}
}